home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Libris Britannia 4
/
science library(b).zip
/
science library(b)
/
TECHNICA
/
COMPUTER
/
H254.ZIP
/
IRITSM3S.ZIP
/
CAGD_LIB
/
CAGDBSUM.C
< prev
next >
Wrap
C/C++ Source or Header
|
1991-10-08
|
5KB
|
120 lines
/******************************************************************************
* CagdBSum.c - Boolean sum surface constructor out of given four curves. *
*******************************************************************************
* Written by Gershon Elber, Sep. 91. *
******************************************************************************/
#ifdef __MSDOS__
#include <stdlib.h>
#include <string.h>
#include <alloc.h>
#endif /* __MSDOS__ */
#include "cagd_loc.h"
/******************************************************************************
* Constructs a boolean sum surface using the four provided boundary curves. *
* Curve end points must meet at the corners if surface boundary should be the *
* same as the four curves. *
******************************************************************************/
CagdSrfStruct *CagdBoolSumSrf(CagdCrvStruct *CrvLeft,
CagdCrvStruct *CrvRight,
CagdCrvStruct *CrvTop,
CagdCrvStruct *CrvBottom)
{
int i, j;
CagdCrvStruct *Crv1, *Crv2;
CagdSrfStruct *Ruled1, *Ruled2, *Ruled3, *Srf;
CagdPtStruct Pt1, Pt2;
CagdRType **SrfPoints, **Ruled1Pts, **Ruled2Pts, **Ruled3Pts;
CrvLeft = CagdCrvCopy(CrvLeft);
CrvRight = CagdCrvCopy(CrvRight);
CrvTop = CagdCrvCopy(CrvTop);
CrvBottom = CagdCrvCopy(CrvBottom);
/* The Left-Right and Top-Bottom curves should share same point/curve */
/* type as well as same order and knot vector (if Bspline representation).*/
CagdMakeCrvsCompatible(&CrvLeft, &CrvRight, TRUE, TRUE);
CagdMakeCrvsCompatible(&CrvTop, &CrvBottom, TRUE, TRUE);
/* The Left-Right and Top-Bottom pairs must share same point/curve type. */
CagdMakeCrvsCompatible(&CrvLeft, &CrvTop, FALSE, FALSE);
CagdMakeCrvsCompatible(&CrvLeft, &CrvBottom, FALSE, FALSE);
CagdMakeCrvsCompatible(&CrvRight, &CrvTop, FALSE, FALSE);
CagdMakeCrvsCompatible(&CrvRight, &CrvBottom, FALSE, FALSE);
/* Now that the curves are in the right representation, form surface(s). */
/* The two ruled surface between the respective curves, in right orders: */
Ruled1 = CagdRuledSrf(CrvLeft, CrvRight,
CrvTop -> Order, CrvTop -> Length);
Ruled2 = CagdRuledSrf(CrvTop, CrvBottom,
CrvRight -> Order, CrvRight -> Length);
Srf = CagdSrfReverse2(Ruled2);
CagdSrfFree(Ruled2);
Ruled2 = Srf;
/* The ruled surface between the four corner points in the right orders. */
CagdCoerceToE3(Pt1.Pt, CrvLeft -> Points, 0, CrvLeft -> PType);
CagdCoerceToE3(Pt2.Pt, CrvLeft -> Points, CrvLeft -> Length - 1,
CrvLeft -> PType);
Crv1 = CagdMergePtPt(&Pt1, &Pt2);
CagdCoerceToE3(Pt1.Pt, CrvRight -> Points, 0, CrvRight -> PType);
CagdCoerceToE3(Pt2.Pt, CrvRight -> Points, CrvRight -> Length - 1,
CrvRight -> PType);
Crv2 = CagdMergePtPt(&Pt1, &Pt2);
/* Should not change CrvLeft/Right only Crv1/2: */
CagdMakeCrvsCompatible(&Crv1, &CrvLeft, TRUE, TRUE);
CagdMakeCrvsCompatible(&Crv2, &CrvRight, TRUE, TRUE);
Ruled3 = CagdRuledSrf(Crv1, Crv2, CrvTop -> Order, CrvTop -> Length);
CagdCrvFree(Crv1);
CagdCrvFree(Crv2);
/* The boolean sum is equal to Ruled1 + Ruled2 - Ruled3. This boolean */
/* sum as computed is not exactly as defined in the literature for non */
/* uniform Bsplines since the ruled surfaces are computed with uniform */
/* distribution along the other axis even if it is non uniform. */
if (CrvRight -> GType == CAGD_CBSPLINE_TYPE) {
Srf = BspSrfNew(Ruled1 -> ULength, Ruled1 -> VLength,
Ruled1 -> UOrder, Ruled1 -> VOrder, Ruled1 -> PType);
CagdFree((VoidPtr) Srf -> UKnotVector);
Srf -> UKnotVector = BspKnotCopy(CrvLeft -> KnotVector,
CrvLeft -> Length + CrvLeft -> Order);
CagdFree((VoidPtr) Srf -> VKnotVector);
Srf -> VKnotVector = BspKnotCopy(CrvTop -> KnotVector,
CrvTop -> Length + CrvTop -> Order);
}
else if (CrvRight -> GType == CAGD_CBEZIER_TYPE)
Srf = BzrSrfNew(Ruled1 -> ULength, Ruled1 -> VLength, Ruled1 -> PType);
else
FATAL_ERROR(CAGD_ERR_POWER_NO_SUPPORT);
SrfPoints = Srf -> Points;
Ruled1Pts = Ruled1 -> Points;
Ruled2Pts = Ruled2 -> Points;
Ruled3Pts = Ruled3 -> Points;
for (i = !CAGD_IS_RATIONAL_SRF(Srf);
i <= CAGD_NUM_OF_PT_COORD(Srf -> PType);
i++) {
CagdRType
*Ruled1PtsPtr = Ruled1Pts[i],
*Ruled2PtsPtr = Ruled2Pts[i],
*Ruled3PtsPtr = Ruled3Pts[i],
*SrfPointsPtr = SrfPoints[i];
for (j = Srf -> ULength * Srf -> VLength; j > 0; j--)
*SrfPointsPtr++ =
*Ruled1PtsPtr++ + *Ruled2PtsPtr++ - *Ruled3PtsPtr++;
}
CagdSrfFree(Ruled1);
CagdSrfFree(Ruled2);
CagdSrfFree(Ruled3);
return Srf;
}